package com.lck.blogmanager.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lck.blogmanager.Enum.AuditTypeEnum;
import com.lck.blogmanager.Enum.CommonEnum;
import com.lck.blogmanager.Enum.FileStatusEnum;
import com.lck.blogmanager.Enum.LikeRelationTypeEnum;
import com.lck.blogmanager.entity.*;
import com.lck.blogmanager.exception.BusinessException;
import com.lck.blogmanager.mapper.AuditMapper;
import com.lck.blogmanager.mapper.CollectMapper;
import com.lck.blogmanager.mapper.FileMapper;
import com.lck.blogmanager.mapper.LikeMapper;
import com.lck.blogmanager.req.*;
import com.lck.blogmanager.res.FileDetailRes;
import com.lck.blogmanager.res.FilePageRes;
import com.lck.blogmanager.res.UserFileDetailRes;
import com.lck.blogmanager.res.UserPageFileRes;
import com.lck.blogmanager.service.FileService;
import com.lck.blogmanager.service.UserService;
import com.lck.blogmanager.util.SecurityUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * @author wyq
 * @version v1.0.0
 * @explain
 * @date 2024/4/7 17:18
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class FileServiceImpl extends ServiceImpl<FileMapper, FileEntity> implements FileService {

    private final UserService userService;
    private final AuditMapper auditMapper;

    private final LikeMapper likeMapper;

    private final CollectMapper collectMapper;

    @Override
    public Integer addFile(AddFileReq req) {
        String suffixName = req.getPath().substring(req.getPath().lastIndexOf("."));
        FileEntity fileEntity = new FileEntity();
        fileEntity.setName(req.getName());
        fileEntity.setFileName(req.getPath());
        fileEntity.setPath(req.getPath());
        fileEntity.setSuffix(suffixName);
        fileEntity.setType(req.getType());
        fileEntity.setUserId(SecurityUtils.getUserId());
        fileEntity.setIntroduce(req.getIntroduce());
        fileEntity.setCollectCount(0);
        fileEntity.setLikeCount(0);
        fileEntity.setDownloadCount(0);
        fileEntity.setStatus(FileStatusEnum.COMMIT.getValue());
        fileEntity.setCreateTime(LocalDateTime.now());
        this.save(fileEntity);
        return fileEntity.getId();
    }

    @Override
    public void userDeleteFile(DeleteFileReq req) {
        //todo 先查出记录，根据文件记录删除真实文件
        //删除文件记录
        this.removeById(req.getId());
        //
    }

    @Override
    public Page<UserPageFileRes> userPageFile(UserPageFileReq req) {
        Page page = new Page(req.getPageNum(),req.getPageSize());
        Page<UserPageFileRes> info = this.getBaseMapper().userPageFile(req,page);
        return info;
    }

    @Override
    public UserFileDetailRes userFileDetail(Integer fileId) {

        Integer userId = SecurityUtils.getUserId();
        FileEntity file = this.getBaseMapper().selectById(fileId);
        if(file==null){
            throw new BusinessException("找不到文件记录，请确认fileid之后重试");
        }
        UserFileDetailRes res = new UserFileDetailRes();
        BeanUtils.copyProperties(file,res);
        UserEntity user = userService.getById(file.getUserId());
        res.setUserName(user.getName());

        //再查点赞信息
        QueryWrapper<LikeEntity> likeWrapper = new QueryWrapper<>();
        likeWrapper.lambda().eq(LikeEntity::getUserId,userId)
                .eq(LikeEntity::getType, LikeRelationTypeEnum.FILE.getValue())
                .eq(LikeEntity::getRelationId,fileId);
        Long likeCount = likeMapper.selectCount(likeWrapper);
        if(likeCount>0){
            res.setIsLike(CommonEnum.YES.getValue());
        }else {
            res.setIsLike(CommonEnum.NO.getValue());
        }
        //收藏信息
        QueryWrapper<CollectEntity> countWrapper = new QueryWrapper<>();
        countWrapper.lambda().eq(CollectEntity::getUserId,userId)
                .eq(CollectEntity::getType, LikeRelationTypeEnum.FILE.getValue())
                .eq(CollectEntity::getRelationId,fileId);
        Long collectCount = collectMapper.selectCount(countWrapper);
        if(collectCount>0){
            res.setIsCollect(CommonEnum.YES.getValue());
        }else {
            res.setIsCollect(CommonEnum.NO.getValue());
        }
        return res;

    }

    @Override
    public Page<FilePageRes> pageFile(FilePageReq req) {
        Page page = new Page(req.getPageNum(),req.getPageSize());
        Page<FilePageRes> res = this.getBaseMapper().pageFile(req,page);
        return res;
    }

    @Override
    public FileDetailRes detail(Integer fileId) {
        //查文件
        FileEntity fileEntity = this.getBaseMapper().selectById(fileId);
        if(fileEntity==null){
            throw new BusinessException("对应文件为空，请检查文件id后重试");
        }
        //查用户
        UserEntity user = userService.getBaseMapper().selectById(fileEntity.getUserId());
        if(user==null){
            throw new BusinessException("找不到对应的用户，请重试");
        }
        //查审核记录
        QueryWrapper<AuditEntity> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(AuditEntity::getType, AuditTypeEnum.FILE.getValue())
                .eq(AuditEntity::getRelationId,fileId);
        List<AuditEntity> audits = auditMapper.selectList(wrapper);
        FileDetailRes res = new FileDetailRes();
        BeanUtils.copyProperties(fileEntity,res);
        res.setUserName(user.getName());
        res.setAuditRecords(audits);
        return res;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void auditFile(AuditFileReq req) {
        //插入审核记录
        AuditEntity audit = new AuditEntity();
        audit.setType(AuditTypeEnum.FILE.getValue());
        audit.setRelationId(req.getId());
        audit.setResult(req.getResult());
        if(audit.getResult()==1){
            audit.setMessage("通过");
        }else {
            audit.setMessage(req.getReason());
        }
        audit.setCreateTime(LocalDateTime.now());
        auditMapper.insert(audit);
        //改博客的状态和博客的审核时间
        FileEntity file = this.getBaseMapper().selectById(req.getId());
        file.setStatus(req.getResult());
        file.setAuditTime(LocalDateTime.now());
        this.saveOrUpdate(file);
    }

    @Override
    public void likeFile(Integer fileId) {
        FileEntity file = this.getById(fileId);


        Integer userId = SecurityUtils.getUserId();
        QueryWrapper<LikeEntity> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(LikeEntity::getType, LikeRelationTypeEnum.FILE.getValue())
                .eq(LikeEntity::getRelationId,fileId)
                .eq(LikeEntity::getUserId,userId);
        LikeEntity entity = likeMapper.selectOne(wrapper);
        if(entity!=null){
            likeMapper.deleteById(entity);
            file.setLikeCount(file.getLikeCount()-1);
            this.saveOrUpdate(file);
        }else {
            LikeEntity like = new LikeEntity();
            like.setType(LikeRelationTypeEnum.FILE.getValue());
            like.setUserId(userId);
            like.setRelationId(fileId);
            likeMapper.insert(like);
            file.setLikeCount(file.getLikeCount()+1);
            this.saveOrUpdate(file);
        }
    }

    @Override
    public void collectFile(Integer fileId) {
        FileEntity file = this.getById(fileId);
        Integer userId = SecurityUtils.getUserId();
        QueryWrapper<CollectEntity> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(CollectEntity::getType, LikeRelationTypeEnum.FILE.getValue())
                .eq(CollectEntity::getRelationId,fileId)
                .eq(CollectEntity::getUserId,userId);
        CollectEntity entity = collectMapper.selectOne(wrapper);
        if(entity!=null){
            collectMapper.deleteById(entity);
            file.setCollectCount(file.getCollectCount()-1);
            this.saveOrUpdate(file);
        }else {
            CollectEntity collect = new CollectEntity();
            collect.setType(LikeRelationTypeEnum.FILE.getValue());
            collect.setUserId(userId);
            collect.setRelationId(fileId);
            collectMapper.insert(collect);
            file.setCollectCount(file.getCollectCount()+1);
            this.saveOrUpdate(file);
        }
    }

    @Override
    public void downloadCount(String path) {
        QueryWrapper<FileEntity> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(FileEntity::getPath,path);
        FileEntity file = this.getOne(wrapper);
        file.setDownloadCount(file.getDownloadCount()+1);
        this.saveOrUpdate(file);
    }

    @Override
    public void userUpdateFile(UpdateFileReq req) {
        String suffixName = req.getPath().substring(req.getPath().lastIndexOf("."));
        FileEntity file = getById(req.getId());
        file.setFileName(req.getName());
        file.setName(req.getName());
        file.setType(req.getType());
        file.setPath(req.getPath());
        file.setIntroduce(req.getIntroduce());
        file.setStatus(FileStatusEnum.COMMIT.getValue());
        file.setSuffix(suffixName);
        saveOrUpdate(file);
    }


}
